home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TEKNO 1998 April
/
TEKNO 4-1998.iso
/
code
/
3dcode.txt
< prev
Wrap
Text File
|
1998-06-28
|
4KB
|
159 lines
Kodsnuttar och formler från "Skapa dina egna virtuella utflykter"
i Tekno 3/98 (med rättningar).
---
type
TPosition = record
x, y, z: real;
end;
var
star: array [1..N_STARS] of TPosition;
type
TVector = TPosition;
TZylon = record
position: TPosition;
velocity: TVector;
end;
var
zylon: array [1..MAX_ZYLONS] of TZylon;
type
TAttitude = record
p, { Pitch }
b, { Bank }
h: real; { Heading }
end;
TShip = record
position: TPosition;
attitude: TAttitude;
v: real; { Speed }
end;
var
ship : TShip;
function translate(const position, origin: TPosition): TPosition;
begin
translate.x := position.x - origin.x;
translate.y := position.y - origin.y;
translate.z := position.z - origin.z;
end;
procedure 2d_rotate(var x, y: real; const angle: real);
var new_x, new_y: real;
begin
new_x := x * cos(angle) + y * sin(angle);
new_y := y * cos(angle) - x * sin(angle);
x := new_x;
y := new_y;
end;
function 3d_rotate(const position: TPosition;
const attitude: TAttitude): TPosition;
var newPosition: TPosition;
begin
{ Initialize }
newPosition := position;
{ Heading }
2d_rotate(newPosition.y, newPosition.x, -attitude.h);
{ Pitch }
2d_rotate(newPosition.z, newPosition.y, attitude.p);
{ Bank }
2d_rotate(newPosition.z, newPosition.x, attitude.b);
{ Done! }
3d_rotate := newPosition;
end;
x' = [ cos(b)cos(h) - sin(h)sin(p)sin(b) ] x +
[-cos(b)sin(h) - sin(p)cos(h)sin(b) ] y +
[ cos(p)sin(b) ] z
y' = [ sin(h)cos(p) ] x +
[ cos(p)cos(h) ] y +
[ sin(p) ] z;
z' = [-cos(h)sin(b) - sin(h)sin(p)cos(b) ] x +
[ sin(h)sin(b) - sin(p)cos(h)cos(b) ] y +
[ cos(p)cos(b) ] z
const
PIXELS_PER_METER = 800 / 0.30;
const
VIEWER_DISTANCE = 0.50; { Meters }
var
mid_u, mid_v: integer;
mid_u := window.width div 2;
mid_v := window.height div 2;
with position do
begin
{ Projection from transformed coordinates to screen }
u := mid_u + trunc((PIXELS_PER_METER * VIEWER_DISTANCE) * (x / y));
v := mid_v - trunc((PIXELS_PER_METER * VIEWER_DISTANCE) * (z / y));
end;
const
COLLISION_DISTANCE = 10; { Meters }
function collided(const position: TPosition): boolean;
{ Must be called with translated position! }
begin
with position do
collided := (x * x + y * y + z * z <
COLLISION_DISTANCE * COLLISION_DISTANCE);
end;
const
ZYLON_SIZE = 10; { Meters }
function scale_factor(const y: real): real;
{ Must be called with Zylon's transformed y coordinate! }
begin
scale_factor := (PIXELS_PER_METER * VIEWER_DISTANCE) * (ZYLON_SIZE / y)
end;
const
SPRITE_SIZE = 128; { Pixels }
type
TSprite = array [0..SPRITE_SIZE - 1,
0..SPRITE_SIZE - 1] of byte;
procedure rescale(const source: TSprite;
var destination: TSprite; const scale_factor: real);
{ If scale_factor < 1.0, destination must be blank }
begin
from_i := 0;
to_i := 0;
repeat
from_j := 0;
to_j := 0;
repeat
destination[to_i, to_j] := source[from_i, from_j];
from_j := trunc(to_j * scale_factor);
to_j := to_j + 1;
until ((from_j >= SPRITE_SIZE) or (to_j >= SPRITE_SIZE));
from_i := trunc(to_i * scale_factor);
to_i := to_i + 1;
until ((from_i >= SPRITE_SIZE) or (to_i >= SPRITE_SIZE));
end;